/*
*GUI.java 
*Santiago Perez
*Galen Marisco
*
*This class handles the GUI features and reading a buffered image.
*
*/
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Desktop;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.awt.image.PixelGrabber;
import java.awt.image.WritableRaster;

import javax.imageio.ImageIO;
import javax.print.DocFlavor.URL;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JFormattedTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.UIManager;
import javax.swing.border.Border;

import  java.text.NumberFormat; 
import java.io.BufferedWriter;
import java.io.EOFException;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;


public class GUI extends JFrame implements ActionListener  {
	//global variables
	JPanel mainPanel,buttonPanel,inSizePanel,inleftPanel,convertOpts,previewPanel;
	JCheckBox shapeD;
	IMGPanel inImagePanel;
	SpinnerNumberModel spinnermodel;
	JSpinner bitdepth;
	JButton browseButton,convertTXTButton,convertHTMLButton,saveButton;
	JTextField qualityText;
	JTextArea previewTextA;
	JLabel chooseQ,inImagesize,outImagesize,bitlabel;
	BufferedImage inImage, outImage;
	JComboBox cboptions;
	String[] conversions ={"","Image->ASCII","Other"};
	int depth;//bit depth selected from the jspinner
	int inFsize, outFsize;
	boolean flag = false;//used for initialization of the checkbox
	final JFileChooser fc = new JFileChooser();
	double[][][] rescaledY =null;int newWidth;int newHeight;int[] split;int stepSize;
	
	
	
	//FOR SHAPE DETECTION, WE NEED A CHECK BOX FOR THIS
	boolean shapeDetection = true;
	
	//CHANGEEEE!!!
	
	//constructor
	public GUI(){
		Font buttonfont= new Font("Consolas",Font.PLAIN,15);
		Font buttonfontSmall= new Font("Consolas",Font.PLAIN,11);
		
		mainPanel = new JPanel(null);
		add(mainPanel);
		inleftPanel = new JPanel(new GridLayout(2,1,15, 20)); 
		inImagePanel = new IMGPanel();
		inImagePanel.setLocation(60, 40);
		inImagePanel.setSize(500,400);
		inImagesize=new JLabel();
		inSizePanel=new JPanel();
		inSizePanel.add(inImagesize);
		inleftPanel.add(inImagePanel);
		inleftPanel.add(inSizePanel);
	
		//panel for the buttons
		buttonPanel=new JPanel(new GridLayout(2,1,15, 10));
		buttonPanel.setLocation(620, 60);
		buttonPanel.setSize(130, 100);
	
		//add buttons and dropdown to coresponding panel
	
		browseButton=new JButton(" Browse");
		browseButton.setLocation(0, 0);
		browseButton.setSize(100,40);
		browseButton.addActionListener(this);
		browseButton.setBackground(Color.LIGHT_GRAY);
		browseButton.setForeground(Color.DARK_GRAY);
		browseButton.setFont(buttonfont);
	
		cboptions=new JComboBox(conversions);
		cboptions.addActionListener(this);
		cboptions.setLocation(0, 60);
		cboptions.setSelectedIndex(0);
		cboptions.setBackground(Color.LIGHT_GRAY);
		cboptions.setForeground(Color.DARK_GRAY);
		cboptions.setFont(buttonfont);
		
		
		convertTXTButton = new JButton("Convert(.txt)");
		convertTXTButton.setLocation(620, 250);
		convertTXTButton.setSize(130,40);
		convertTXTButton.addActionListener(this);
		convertTXTButton.setBackground(Color.LIGHT_GRAY);
		convertTXTButton.setForeground(Color.DARK_GRAY);
		convertTXTButton.setFont(buttonfontSmall);
		
		
		convertHTMLButton = new JButton("Convert(.html)");
		convertHTMLButton.setLocation(620, 300);
		convertHTMLButton.setSize(130,40);
		convertHTMLButton.addActionListener(this);
		convertHTMLButton.setBackground(Color.LIGHT_GRAY);
		convertHTMLButton.setForeground(Color.DARK_GRAY);
		convertHTMLButton.setFont(buttonfontSmall);
		
	
		//options that Image->ASCII provides
		convertOpts=new JPanel(new GridLayout(3,1,5,5));
		convertOpts.setSize(130, 60);
		convertOpts.setLocation(620, 165);
		
		
		
		spinnermodel=new SpinnerNumberModel(0, 0, 3, 1);//between 1 and 3 bits
		bitdepth= new JSpinner(spinnermodel);
		bitdepth.setVisible(false);
		bitlabel= new JLabel("Choose bit depth:");
		bitlabel.setFont(buttonfontSmall);
		bitlabel.setVisible(false);
		
		convertOpts.add(bitlabel);
		convertOpts.add(bitdepth);
		
		shapeD = new JCheckBox("Shape Detection");
	    shapeD.setMnemonic(KeyEvent.VK_S); 
	    shapeD.setFont(buttonfontSmall);
	    shapeD.setSelected(true);
	    shapeD.setVisible(false);
	   
	    convertOpts.add(shapeD);
	    
		saveButton= new JButton("Save");
		saveButton.setSize(130, 40);
		saveButton.setLocation(620,380 );
		saveButton.addActionListener(this);
		saveButton.setBackground(Color.LIGHT_GRAY);
		saveButton.setForeground(Color.DARK_GRAY);
		saveButton.setFont(buttonfont);
		
		buttonPanel.add(browseButton);
		buttonPanel.add(cboptions);
	
		previewPanel=new JPanel(new BorderLayout());
		previewPanel.setLocation(775, 40);
		previewPanel.setSize(500,400);
		previewTextA=new JTextArea();
		
		outImagesize= new JLabel();
		outImagesize.setLocation(800, 420);
	
		//adding to the mainPanel to be displayed
		mainPanel.add(inImagePanel);
		mainPanel.add(inleftPanel);
		mainPanel.add(buttonPanel);
		mainPanel.add(convertTXTButton);
		mainPanel.add(convertHTMLButton);
		mainPanel.add(convertOpts);
		mainPanel.add(saveButton);
		mainPanel.add(previewPanel);
		mainPanel.add(outImagesize);
	}//end constructor
	
	@Override
	public void actionPerformed(ActionEvent act) {
		int w;//width of inImage
		int h;//height of inImage
		int slopt = cboptions.getSelectedIndex();//the selected option
		ICompressor mycomp = new ICompressor();
		

		/****************************************************************
		 **********************     OPEN            *********************
		 ****************************************************************/
		if(act.getSource() == browseButton){
			fc.addChoosableFileFilter(new ImageFilter());
        	fc.setAcceptAllFileFilterUsed(false);
    		//fc.setBackground(Color.LIGHT_GRAY);
    		//fc.setForeground(Color.DARK_GRAY);
    		
			int returnVal = fc.showOpenDialog(GUI.this);
			if(returnVal == JFileChooser.APPROVE_OPTION){
				File file = fc.getSelectedFile();
				long fileSizeInBytes = file.length();
				// Convert the bytes to Kilobytes (1 KB = 1024 Bytes)
				long fileSizeInKB = fileSizeInBytes / 1024;
				// Convert the KB to MegaBytes (1 MB = 1024 KBytes)
				long fileSizeInMB = fileSizeInKB / 1024;
				inFsize=(int) fileSizeInKB;	
				try{
					inImage=ImageIO.read(file);
					inImagePanel.setBufferedImage(inImage);					
				}catch(Exception e){
					e.printStackTrace();
				}//end try/catch block	
			}//end if
		}else if(act.getSource()==cboptions){
			if(slopt == 1){
				updateconvertOpts(1);
			}else if(slopt == 0){
					updateconvertOpts(0);
			}//end if/else block
		}//end OPEN if/else
		
		
		/****************************************************************
		 **********************     CONVERT  toTXT      *********************
		 ****************************************************************/
		else if (act.getSource() == convertTXTButton){
			if(inImage == null){
				JOptionPane.showMessageDialog(null, "Please Select an image first");
				return;
			}//end if
			w = inImage.getWidth(null);
			h = inImage.getHeight(null);	 
			int[] inputVal = new int[h*w];
			int[] YVal     = new int[h*w];// for the options in dropdown menu 0 1 2
			int red,green, blue; 
			PixelGrabber grabber = new PixelGrabber(inImage.getSource(),0,0,w,h,inputVal,0,w);
			try{
				grabber.grabPixels();
			}catch(Exception e){
				e.printStackTrace();
				JComboBox cb= (JComboBox)act.getSource();
			}//end try/catch block 
			
			//convert the image to TXT
			if(slopt == 1){
				previewPanel.add(previewTextA);
				System.out.println("Image size: " +w +" by "+ h+ "pixels" );
				depth=(int)bitdepth.getValue();
				if(depth==0){
					depth=1;
				}
				shapeDetection=shapeD.isSelected();
				System.out.println("Checkbox"+shapeDetection);
				mycomp.processImage(inImage,depth, shapeDetection);
				rescaledY=mycomp.getrescaledY();
				 
				
				newWidth=mycomp.getNewWidth();
				newHeight=mycomp.getNewHeight();
				split=mycomp.getSplit();
				stepSize=mycomp.getstepSize();
				
			//show the preview
				mycomp.printBitMapToFile(rescaledY,newWidth,newHeight,stepSize,split,depth, shapeDetection);
				String resultImage= getImageData();
	        	Font custfont= new Font("Consolas",Font.PLAIN,3);
	        	previewTextA.setText(resultImage);
	        	previewTextA.setAlignmentY(300);
	        	previewTextA.setFont(custfont);
	        	previewTextA.setEditable(false);				
			//Save the image as TXT
				try{
        			Runtime.getRuntime().exec("notepad picture.txt");
        			 /*  File file = new File("c.html");

  			       	try {
  			            Desktop desktop = Desktop.getDesktop();
  			            desktop.open(file);
  			        } catch (IOException e) {
  			            e.printStackTrace();
  			        }*/
        		}catch(IOException e){
        		}//end try/catch
        	}//end if		
		}//end CONVERT to TXT
	
		/****************************************************************
		 **********************     CONVERT  toHTML     *********************
		 ****************************************************************/

		
		else if (act.getSource() == convertHTMLButton){
			if(inImage == null){
				JOptionPane.showMessageDialog(null, "Please Select an image first");
				return;
			}//end if
			w = inImage.getWidth(null);
			h = inImage.getHeight(null);	 
			int[] inputVal = new int[h*w];
			int[] YVal     = new int[h*w];// for the options in dropdown menu 0 1 2
			int red,green, blue; 
			PixelGrabber grabber = new PixelGrabber(inImage.getSource(),0,0,w,h,inputVal,0,w);
			try{
				grabber.grabPixels();
			}catch(Exception e){
				e.printStackTrace();
				JComboBox cb= (JComboBox)act.getSource();
			}//end try/catch block 
			
			//convert the image to TXT
			if(slopt == 1){
				previewPanel.add(previewTextA);
				System.out.println("Image size: " +w +" by "+ h+ "pixels" );
				depth=(int)bitdepth.getValue();
				if(depth==0){
					depth=1;
				}
				shapeDetection=shapeD.isSelected();
				mycomp.processImage(inImage,depth, shapeDetection);
				rescaledY=mycomp.getrescaledY();
				newWidth=mycomp.getNewWidth();
				newHeight=mycomp.getNewHeight();
				split=mycomp.getSplit();
				stepSize=mycomp.getstepSize();
			//show the preview
				mycomp.printBitMapToFileHTML(rescaledY,newWidth,newHeight,stepSize,split,depth, shapeDetection);
				String resultImage= getImageData();
	        	Font custfont= new Font("Consolas",Font.PLAIN,3);
	        	previewTextA.setText(resultImage);
	        	previewTextA.setAlignmentY(300);
	        	previewTextA.setFont(custfont);
	        	previewTextA.setEditable(false);				
			//Save the image as HTML
        			//Runtime.getRuntime().exec("notepad picture.txt");
        			File file = new File("picture.html");
  			       	try {
  			            Desktop desktop = Desktop.getDesktop();
  			            desktop.open(file);
  			        } catch (IOException e) {
  			            e.printStackTrace();
  			        }//end try/catch
        	}//end if		
		}//end CONVERT to HTML
		
        		
        
	}//end actionperformed	
	
	/********EXTRA FUNCTIONS***********
	 *********************************
	 **********************************/
	public void updateconvertOpts(int i) {
		//1=ImagetoAscii
		if(i == 1){
			bitdepth.setVisible(true);
			bitlabel.setVisible(true);
			shapeD.setVisible(true);
			flag=true;
			System.out.println("1");
		}else if (i == 0 && flag == true){
			bitdepth.setVisible(false);
			bitlabel.setVisible(false);
			shapeD.setVisible(false);
		}//end if/else block
	}//end updateconvertOpts
	public String getImageData(){    
        char ch;  
        int in = 0;  
        String strTest = "";  
          
        try{  
            FileReader charRead = new FileReader("picture.txt");  
            while (in != -1){  
             in = charRead.read();  
             ch = (char)in;  
             strTest = strTest + ch;   
            }  
        }catch (EOFException e){  
            System.out.println("We have reached the end of the file: " + e);  
        }catch(IOException e){   
            System.out.println("Error reading file: " + e);  
        }//end try/catch block  
        return strTest;  
    }//end readDataImage  

}//end class
